home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / lib / calc / help / obj < prev    next >
Text File  |  1995-07-17  |  7KB  |  177 lines

  1. Using objects
  2.  
  3.     Objects are user-defined types which are associated with user-
  4.     defined functions to manipulate them.  Object types are defined
  5.     similarly to structures in C, and consist of one or more elements.
  6.     The advantage of an object is that the user-defined routines are
  7.     automatically called by the calculator for various operations,
  8.     such as addition, multiplication, and printing.  Thus they can be
  9.     manipulated by the user as if they were just another kind of number.
  10.  
  11.     An example object type is "surd", which represents numbers of the form
  12.  
  13.         a + b*sqrt(D),
  14.  
  15.     where D is a fixed integer, and 'a' and 'b' are arbitrary rational
  16.     numbers.  Addition, subtraction, multiplication, and division can be
  17.     performed on such numbers, and the result can be put unambiguously
  18.     into the same form.  (Complex numbers are an example of surds, where
  19.     D is -1.)
  20.  
  21.     The "obj" statement defines either an object type or an actual
  22.     variable of that type.  When defining the object type, the names of
  23.     its elements are specified inside of a pair of braces.  To define
  24.     the surd object type, the following could be used:
  25.  
  26.         obj surd {a, b};
  27.  
  28.     Here a and b are the element names for the two components of the
  29.     surd object.  An object type can be defined more than once as long
  30.     as the number of elements and their names are the same.
  31.  
  32.     When an object is created, the elements are all defined with zero
  33.     values.  A user-defined routine should be provided which will place
  34.     useful values in the elements.  For example, for an object of type
  35.     'surd', a function called 'surd' can be defined to set the two
  36.     components as follows:
  37.  
  38.         define surd(a, b)
  39.         {
  40.             local x;
  41.  
  42.             obj surd x;
  43.             x.a = a;
  44.             x.b = b;
  45.             return x;
  46.         }
  47.  
  48.     When an operation is attempted for an object, user functions with
  49.     particular names are automatically called to perform the operation.
  50.     These names are created by concatenating the object type name and
  51.     the operation name together with an underscore.  For example, when
  52.     multiplying two objects of type surd, the function "surd_mul" is
  53.     called.
  54.  
  55.     The user function is called with the necessary arguments for that
  56.     operation.  For example, for "surd_mul", there are two arguments,
  57.     which are the two numbers.  The order of the arguments is always
  58.     the order of the binary operands.  If only one of the operands to
  59.     a binary operator is an object, then the user function for that
  60.     object type is still called.  If the two operands are of different
  61.     object types, then the user function that is called is the one for
  62.     the first operand.
  63.  
  64.     The above rules mean that for full generality, user functions
  65.     should detect that one of their arguments is not of its own object
  66.     type by using the 'istype' function, and then handle these cases
  67.     specially.  In this way, users can mix normal numbers with object
  68.     types.  (Functions which only have one operand don't have to worry
  69.     about this.)  The following example of "surd_mul" demonstrates how
  70.     to handle regular numbers when used together with surds:
  71.  
  72.         define surd_mul(a, b)
  73.         {
  74.             local x;
  75.  
  76.             obj surd x;
  77.             if (!istype(a, x)) {    
  78.                 /* a not of type surd */
  79.                 x.a = b.a * a;
  80.                 x.b = b.b * a;
  81.             } else if (!istype(b, x)) {
  82.                 /* b not of type surd */
  83.                 x.a = a.a * b;
  84.                 x.b = a.b * b;
  85.             } else {            
  86.                 /* both are surds */
  87.                 x.a = a.a * b.a + D * a.b * b.b;
  88.                 x.b = a.a * b.b + a.b * b.a;
  89.             }
  90.             if (x.b == 0)
  91.                 return x.a;    /* normal number */
  92.             return x;        /* return surd */
  93.         }
  94.  
  95.     In order to print the value of an object nicely, a user defined
  96.     routine can be provided.  For small amounts of output, the print
  97.     routine should not print a newline.  Also, it is most convenient
  98.     if the printed object looks like the call to the creation routine.
  99.     For output to be correctly collected within nested output calls,
  100.     output should only go to stdout.  This means use the 'print'
  101.     statement, the 'printf' function, or the 'fprintf' function with
  102.     'files(1)' as the output file.  For example, for the "surd" object:
  103.  
  104.         define surd_print(a)
  105.         {
  106.             print "surd(" : a.a : "," : a.b : ")" : ;
  107.         }
  108.  
  109.     It is not necessary to provide routines for all possible operations
  110.     for an object, if those operations can be defaulted or do not make
  111.     sense for the object.  The calculator will attempt meaningful
  112.     defaults for many operations if they are not defined.  For example,
  113.     if 'surd_square' is not defined to square a number, then 'surd_mul'
  114.     will be called to perform the squaring.  When a default is not
  115.     possible, then an error will be generated.
  116.  
  117.     Please note: Arguments to object functions are always passed by
  118.     reference (as if an '&' was specified for each variable in the call).
  119.     Therefore, the function should not modify the parameters, but should
  120.     copy them into local variables before modifying them.  This is done
  121.     in order to make object calls quicker in general.
  122.  
  123.     The double-bracket operator can be used to reference the elements
  124.     of any object in a generic manner.  When this is done, index 0
  125.     corresponds to the first element name, index 1 to the second name,
  126.     and so on.  The 'size' function will return the number of elements
  127.     in an object.
  128.  
  129.     The following is a list of the operations possible for objects.
  130.     The 'xx' in each function name is replaced with the actual object
  131.     type name.  This table is displayed by the 'show objfuncs' command.
  132.  
  133.         Name    Args    Comments
  134.  
  135.         xx_print    1    print value, default prints elements
  136.         xx_one      1    multiplicative identity, default is 1
  137.         xx_test     1    logical test (false,true => 0,1), 
  138.                     default tests elements
  139.         xx_add      2    
  140.         xx_sub      2    subtraction, default adds negative
  141.         xx_neg      1    negative
  142.         xx_mul      2    
  143.         xx_div      2    non-integral division, default multiplies 
  144.                     by inverse
  145.         xx_inv      1    multiplicative inverse
  146.         xx_abs      2    absolute value within given error
  147.         xx_norm     1    square of absolute value
  148.         xx_conj     1    conjugate
  149.         xx_pow      2    integer power, default does multiply, 
  150.                     square, inverse
  151.         xx_sgn      1    sign of value (-1, 0, 1)
  152.         xx_cmp      2    equality (equal,non-equal => 0,1), 
  153.                     default tests elements
  154.         xx_rel      2    inequality (less,equal,greater => -1,0,1)
  155.         xx_quo      2    integer quotient
  156.         xx_mod      2    remainder of division
  157.         xx_int      1    integer part
  158.         xx_frac     1    fractional part
  159.         xx_inc      1    increment, default adds 1
  160.         xx_dec      1    decrement, default subtracts 1
  161.         xx_square   1    default multiplies by itself
  162.         xx_scale    2    multiply by power of 2
  163.         xx_shift    2    shift left by n bits (right if negative)
  164.         xx_round    2    round to given number of decimal places
  165.         xx_bround   2    round to given number of binary places
  166.         xx_root     3    root of value within given error
  167.         xx_sqrt     2    square root within given error
  168.  
  169.  
  170.     Also see the library files:
  171.  
  172.         dms.cal
  173.         mod.cal
  174.         poly.cal
  175.         quat.cal
  176.         surd.cal
  177.